/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * BrewForcastFrame.java
 *
 * Created on Apr 4, 2011, 3:30:36 PM
 */

package gbbmgmt;

import java.util.*;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.text.ParseException;

import org.jdesktop.application.Action;
import javax.swing.JOptionPane;



import org.jdesktop.application.Action;

/**
 *
 * @author dchapman
 */
public class BrewForcastFrame extends javax.swing.JFrame {

    public ArrayList<String[]> Beers;
    public ArrayList<String[]> Results;

    public String txtToDisp = "";

    public Calendar calendar = Calendar.getInstance();
    public SimpleDateFormat dform = new SimpleDateFormat("dd");
    public SimpleDateFormat mform = new SimpleDateFormat("MM");
    public SimpleDateFormat yform = new SimpleDateFormat("yyyy");

    public Date today = calendar.getTime();

    public ArrayList<String[]> Sales;
    public ArrayList<String[]> SalesSort;
    public ArrayList<String[]> CurState;
    public ArrayList<String[]> timevols;
    public ArrayList<String[]> inventory;
    public ArrayList<String[]> Schedule;
    public int totalNum = 0;
    public double maxval = 0;
    public double[] vols;

    //variable place holder
    private int iyear = 0;
    private int imonth = 0;

    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

    /** Creates new form BrewForcastFrame */
    public BrewForcastFrame() {
        initComponents();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        jTextArea1 = new javax.swing.JTextArea();
        jButtonForcast = new javax.swing.JButton();
        jButton1 = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setName("Form"); // NOI18N

        jScrollPane1.setName("jScrollPane1"); // NOI18N

        jTextArea1.setColumns(20);
        jTextArea1.setRows(5);
        jTextArea1.setName("jTextArea1"); // NOI18N
        jScrollPane1.setViewportView(jTextArea1);

        javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(gbbmgmt.GBBMGMTApp.class).getContext().getActionMap(BrewForcastFrame.class, this);
        jButtonForcast.setAction(actionMap.get("RunForcast")); // NOI18N
        org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(gbbmgmt.GBBMGMTApp.class).getContext().getResourceMap(BrewForcastFrame.class);
        jButtonForcast.setText(resourceMap.getString("jButtonForcast.text")); // NOI18N
        jButtonForcast.setName("jButtonForcast"); // NOI18N

        jButton1.setAction(actionMap.get("Exit_Rep")); // NOI18N
        jButton1.setText(resourceMap.getString("jButton1.text")); // NOI18N
        jButton1.setName("jButton1"); // NOI18N

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 734, Short.MAX_VALUE)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jButtonForcast)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 576, Short.MAX_VALUE)
                .addComponent(jButton1)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 407, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jButtonForcast)
                    .addComponent(jButton1))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new BrewForcastFrame().setVisible(true);
            }
        });
    }

    @Action
    public void RunForcast() {
        DBA.openDBCon();
        Beers = DBA.RunSQLQuery("SELECT BId,RecipeID,BName FROM Beer WHERE BCost='1'");
        DBA.closeDBCon();

        totalNum = 0;
        LoadData();
    
        int day = Integer.parseInt(dform.format(today));
        int month = Integer.parseInt(mform.format(today));
        int year = Integer.parseInt(yform.format(today));

        txtToDisp = "Brew Schedule Forcasting Report \n \n";
        txtToDisp += today.toString() + "\n";
        txtToDisp += dform.format(today) + " - " + mform.format(today) + " - " +
                yform.format(today) + "\n";

        String[] rec = new String[2];
        Schedule = new ArrayList<String[]>();

        for(String s[] : Beers){
            txtToDisp += "--" + s[2]+ " --\n";
            rec[0] = s[2];
            //Calculate the average brew requirements for given beer.
            double avg = AvgBeerTime(s[0]);
            txtToDisp += "Average days for primary = " + Double.toString(avg) + "\n";
            //Parse through beer volumes sold per month and calculate average increase in sales per month.
            ParseVolumes(s[0]);
            double avgDelta=0;
            double lastVol = 0;
            for(int i=1; i<totalNum; i++){
                avgDelta += vols[i] - vols[i-1];
                lastVol = vols[i];
            }
            avgDelta = avgDelta / (totalNum-1);
            txtToDisp += "Average increase in sales / month = " + Double.toString(avgDelta) + " BBL\n";
            //Fine what is currently in process and fill out timevols array.
            CurrentVolume(s[0], (int)avg, 7);

            //Now find current inventory.
            double curinv = CurrentInventory(s[0]);
            txtToDisp += Double.toString(curinv) + " BBL in Stock\n";

            //If time has already passed, add volumes to current inventory.
            for(String x[] : timevols){
                try {
                    Date pStart = today;
                    pStart = (Date)dateFormat.parse(x[0]);

                    if(pStart.before(today)){
                        curinv += Double.valueOf(x[1].trim()).doubleValue();
                    }
                } catch (ParseException e){
                   e.printStackTrace();
                }
            }
            double futurevolume = lastVol + avgDelta;
            double dailyvol = futurevolume/30;

            Date curDay = today;
            Calendar date = Calendar.getInstance();
            date.setTime(curDay);

            Calendar datefin = Calendar.getInstance();
            datefin.setTime(curDay);
            datefin.add(Calendar.MONTH, 3);
            Date findate = new Date(datefin.getTime().getTime());

            Date BrewDate = today;

            while(curDay.before(findate)){
                //Check if more stock should be added.
                for(String x[] : timevols){
                    try {
                        Date pStart = today;
                        pStart = (Date)dateFormat.parse(x[0]);
                        if(pStart.equals(curDay)){
                            curinv += Double.valueOf(x[1].trim()).doubleValue();
                        }
                    } catch (ParseException e){
                       e.printStackTrace();
                    }
                }
                //Decrement Volume
                curinv = curinv - dailyvol;
                if(curinv<=0){
                    txtToDisp += "Out of stock on " + dateFormat.format(curDay) + "\n";
                    BrewDate = curDay;
                    curDay = findate;
                } else {
                    //Increment date by one day.
                    date.add(Calendar.DAY_OF_MONTH, 1);
                    curDay = new Date(date.getTime().getTime());
                }
            }

            //BrewDate contains the day we will run out of stock, now back calculate.
            double days = avg + 7;
            days = days * (-1);
            Calendar BrewTime = Calendar.getInstance();
            BrewTime.setTime(BrewDate);
            BrewTime.add(Calendar.DAY_OF_MONTH, (int)days);
            Date Brewday = new Date(BrewTime.getTime().getTime());

            txtToDisp += "Next Batch Must Be Brewed By: " + dateFormat.format(Brewday) + "\n\n";
            rec[1] = dateFormat.format(Brewday);
            Schedule.add(rec);
        }

        String Priority = "Brewing Priority\n";

        Date curDay = today;
        Calendar date = Calendar.getInstance();
        date.setTime(curDay);

        Calendar datefin = Calendar.getInstance();
        datefin.setTime(curDay);
        datefin.add(Calendar.MONTH, 3);
        Date findate = new Date(datefin.getTime().getTime());

        while(curDay.before(findate)){
            for(String p[] : Schedule){
                try {
                    Date pStart = today;
                    pStart = (Date)dateFormat.parse(p[1]);
                    if(pStart.equals(curDay)){
                        Priority += p[0] + " brewed by " + p[1] + "\n";
                    }
                } catch (ParseException e){
                   e.printStackTrace();
                }
            }
            //Increment date by one day.
            date.add(Calendar.DAY_OF_MONTH, 1);
            curDay = new Date(date.getTime().getTime());
        }

        txtToDisp += Priority;

        jTextArea1.setText(txtToDisp);
    }

    public double AvgBeerTime(String BeerID){
        DBA.openDBCon();
        Results = DBA.RunSQLQuery("SELECT BID,PFDate01,SFDate01 FROM Brews WHERE BBeerID='" + BeerID + "'");
        DBA.closeDBCon();

        double sum = 0;
        double total = 0;

        for(String s[] : Results){
            try {
                Date pStart = today;
                Date sStart = today;
                if((s[1] != null)&&(s[2] != null)){
                    pStart = (Date)dateFormat.parse(s[1]);
                    sStart = (Date)dateFormat.parse(s[2]);
                    Calendar date = Calendar.getInstance();
                    date.setTime(pStart);
                    Calendar findate = Calendar.getInstance();
                    findate.setTime(sStart);
                    int daysBetween = 0;
                    while (date.before(findate)){
                        date.add(Calendar.DAY_OF_MONTH, 1);
                        daysBetween++;
                    }
                    if(daysBetween>0){
                        sum += daysBetween;
                        total++;
                    }
                    
                }
            } catch (ParseException e){
               e.printStackTrace();
            }
        }
        double avg = (double)sum/(double)total;
        return avg;
    }

    public void LoadData() {
        //Redraw screen to clean.
        totalNum = 0;

        Date stp = today;
        java.sql.Date StopDate = new java.sql.Date( stp.getTime() );


        //Read all sales for given dates from database.
        DBA.openDBCon();
        String query = "SELECT SId,CustID,BeerID,SDate,NumHalf,NumQtr,NumSix,NumTT,NumTW,NumSF" +
                " FROM Sales WHERE SDate<='" +
                StopDate.toString() + "'";
        Sales = DBA.RunSQLQuery(query);
        DBA.closeDBCon();

        //Determine Month and Year of start date for sorting.
        imonth = 7;
        iyear = 2010;

        SalesSort = new ArrayList<String[]>();

        //Parse through sales and separate into appropriate arrays.
        for(String s[] : Sales){
            //Find which month / year record is for and add it to bucket.
            String modDate = s[3].substring(0,(s[3].length()-14));
            String dateYear = modDate.substring(0,modDate.length()-3);
            String dateMonth = modDate.substring(5,modDate.length());
            int idateYear = Integer.parseInt(dateYear.trim());
            int idateMonth = Integer.parseInt(dateMonth.trim());

            //Parse through array and find larger datevalue for array list size.
            int datenum = (idateMonth - imonth + 1) + (12*(idateYear - iyear));

            //Get Values of kegs.
            int nhlf = Integer.parseInt(s[4].trim());
            int nqtr = Integer.parseInt(s[5].trim());
            int nsix = Integer.parseInt(s[6].trim());
            int ntt = Integer.parseInt(s[7].trim());
            int ntw = Integer.parseInt(s[8].trim());
            int nsf = Integer.parseInt(s[9].trim());

            double volume = ((double)nhlf/2) + ((double)nqtr/4) + ((double)nsix/6);
            volume += ((double)ntt*(double)Global.TwentyTwoCase) * Global.TTtoBBL;
            volume += ((double)ntw*(double)Global.TwelveCase) * Global.TWtoBBL;
            volume += ((double)nsf*(double)Global.SevenFiftyCase) * Global.SFtoBBL;

            //Fill out new array list.
            String[] record = new String[10];
            record[0] = Integer.toString(datenum);
            record[1] = s[1];
            record[2] = s[2];
            record[3] = Double.toString(volume);

            SalesSort.add(record);
            if(totalNum<datenum){
                totalNum=datenum;
            }
        }
    }
    
    public void ParseVolumes(String BeerID){
        //Go through sales sort and parse volumes into buckets.
        vols = new double[totalNum];

        for(String s[] : SalesSort){
            if(s[2].equals(BeerID)){
                int idx = Integer.parseInt(s[0].trim())-1;
                double value = Double.valueOf(s[3].trim()).doubleValue();
                double volume = vols[idx] + value;
                if(maxval<volume)maxval=volume;
                vols[idx] = volume;
            }
        }
    }

    public void CurrentVolume(String BeerID, int daysPrimary, int daysLager){
        DBA.openDBCon();
        String query = "SELECT BState,PFDate01,VolLeft,SFDate01,SFVol01,CTDate,CTVol" +
                " FROM Brews WHERE BBeerID='" + BeerID + "' AND BState<20";
        CurState = DBA.RunSQLQuery(query);
        DBA.closeDBCon();

        timevols = new ArrayList<String[]>();

        for(String s[] : CurState){
            String[] record = new String[2];

            int daystot = 0;

            if(s[0].equals("5")){
                //Calculate time required for brew to complete.
                //PFDate01 + Avg time to ferment + daysPrimary + LagerTime
                daystot = daysPrimary + daysLager;
                try {
                    Date pStart = today;
                    pStart = (Date)dateFormat.parse(s[1]);
                    Calendar date = Calendar.getInstance();
                    date.setTime(pStart);
                    date.add(Calendar.DAY_OF_MONTH, daystot);
                    Date dte = new Date(date.getTime().getTime());
                    record[0] = dateFormat.format(dte);
                    record[1] = s[2];
                    timevols.add(record);
                } catch (ParseException e){
                   e.printStackTrace();
                }
            } else if(s[0].equals("10")){
                daystot = daysLager;
                try {
                    Date pStart = today;
                    pStart = (Date)dateFormat.parse(s[3]);
                    Calendar date = Calendar.getInstance();
                    date.setTime(pStart);
                    date.add(Calendar.DAY_OF_MONTH, daystot);
                    Date dte = new Date(date.getTime().getTime());
                    record[0] = dateFormat.format(dte);
                    record[1] = s[4];
                    timevols.add(record);
                } catch (ParseException e){
                   e.printStackTrace();
                }
            } else if(s[0].equals("15")){
                daystot = 1;
                try {
                    Date pStart = today;
                    pStart = (Date)dateFormat.parse(s[5]);
                    Calendar date = Calendar.getInstance();
                    date.setTime(pStart);
                    date.add(Calendar.DAY_OF_MONTH, daystot);
                    Date dte = new Date(date.getTime().getTime());
                    record[0] = dateFormat.format(dte);
                    record[1] = s[6];
                    timevols.add(record);
                } catch (ParseException e){
                   e.printStackTrace();
                }
            }
        }
    }

    public double CurrentInventory(String BeerID){
        DBA.openDBCon();
        String query = "SELECT BIHalf,BIQtr,BISix,BITT,BITW,BISF" +
                " FROM BeerInventory WHERE BIBId='" + BeerID + "'";
        inventory = DBA.RunSQLQuery(query);
        DBA.closeDBCon();

        double volume = 0;

        for(String s[] : inventory){
            volume = (Double.valueOf(s[0].trim()).doubleValue())/2;
            volume += (Double.valueOf(s[1].trim()).doubleValue())/4;
            volume += (Double.valueOf(s[2].trim()).doubleValue())/6;
            volume += (Double.valueOf(s[3].trim()).doubleValue())*Global.TTtoBBL;
            volume += (Double.valueOf(s[4].trim()).doubleValue())*Global.TWtoBBL;
            volume += (Double.valueOf(s[5].trim()).doubleValue())*Global.SFtoBBL;
        }

        return volume;
    }

    @Action
    public void Exit_Rep() {
        dispose();
    }
      

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButtonForcast;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTextArea jTextArea1;
    // End of variables declaration//GEN-END:variables

}
